/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
// l4scrn.hpp - Linear screen driver for 4 bpp (16 color/grayscale) operation.
//
// Author: Ken Maxwell
//
// Copyright (c) 1997-2009 Swell Software 
//              All Rights Reserved.
//
// Unauthorized redistribution of this source code, in whole or part,
// without the express written permission of Swell Software
// is strictly prohibited.
//
// Notes:
//
//  This screen driver is intended for use with monochrome systems that support
//  a linear frame buffer. Example controllers include the SMOS 135xx series,
//  the MPC823, SC300, and many others. 
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/

#ifndef _L4SCREEN_
#define _L4SCREEN_

                     
/*--------------------------------------------------------------------------*/
#ifndef PLOTPOINTVIEW_AS_FUNCTION
 #ifndef CUSTOM_PLOTPOINT_MACRO
 #define PlotPointView(x, y, c)\
{\
    PEGUBYTE *_Put = SCANLINESTART(y) + (x >> 1);\
    PEGUBYTE _uVal = *_Put;\
    if (x & 1)\
    {\
        _uVal &= 0xf0;\
        _uVal |= c;\
    }\
    else\
    {\
        _uVal &= 0x0f;\
        _uVal |= (c) << 4;\
    }\
    *_Put = _uVal;\
}
#endif
#endif


/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
class L4Screen : public PegScreen
{
    public:
        L4Screen(const PegRect &);
        virtual ~L4Screen();

        virtual void Capture(PegCapture *Info, PegRect &Rect);

        virtual PegBitmap *CreateBitmap(PEGINT Width, PEGINT Height,
            PEGINT Style = BMF_RAW | BMF_HAS_TRANS);

        virtual PEGUBYTE *GetPalette(PEGULONG *pPutSize);

       #ifdef PEG_IMAGE_SCALING
        virtual PEGCOLOR GetBitmapPixel(PEGINT x, PEGINT y, PegBitmap *pMap)
        {
            PEGCOLOR *_pGet = pMap->pStart;
            if (pMap->BitsPix == 8)
            {
                _pGet += pMap->Width * y;
                _pGet += x;
                return *_pGet;
            }

            PEGUINT wBytesPerLine = (pMap->Width + 3) >> 2;
            _pGet += wBytesPerLine * y;
            _pGet += x >> 2;
            PEGUBYTE _uVal = *_pGet;
            PEGUBYTE _uShift = 6 - ((x & 3) << 1);
            _uVal >>= _uShift;
            _uVal &= 3;
            return ((PEGCOLOR) _uVal);           
        }
       #endif

        virtual PEGCOLOR GetPixelView(PEGINT x, PEGINT y)
        {
            if (mpContext)
            {                
                PEGUBYTE *_Get = (PEGCOLOR *)SCANLINESTART(y) + (x >> 2);                
                PEGUBYTE _uShift = 6 - ((x & 3) << 1);
                PEGUBYTE _uVal = *_Get;
                _uVal >>= _uShift;
                _uVal &= 3;
                return ((PEGCOLOR) _uVal);
            }
            else
            {
                return 0;
            }
        }

       #ifdef PEG_IMAGE_SCALING
        virtual void PutBitmapPixel(PEGINT x, PEGINT y, PegBitmap *pMap, 
                                    PEGCOLOR cVal)
        { 
            PEGUINT wBytesPerLine = (pMap->Width + 3) >> 2;
            PEGCOLOR *_pPut = pMap->pStart;
            _pPut += wBytesPerLine * y;
            _pPut += x >> 2;
            PEGUBYTE _uShift = 6 - ((x & 3) << 1);
            PEGUBYTE _uVal = *_pPut;
            _uVal &= ~(0x03 << _uShift);
            _uVal |= cVal << _uShift;
            *_pPut = _uVal;
        }
       #endif

        virtual void ResetPalette(void);
        virtual void SetPalette(PEGINT First, PEGINT Num, 
                                const PEGUBYTE *pGet);

    protected:

        virtual void BitmapView(const PegPoint Where, 
                                const PegBitmap *pGetmap, 
                                const PegRect &View);
       
       #if defined(PEG_MULT_SOFT_SURFACES)

        PEGBOOL BuildCompositeSurface(PegRect &Copy, PEGUBYTE *pComposite);

        void CopySurface(DrawSurface *pSurface, PegRect &Copy,
            PEGUBYTE *pComposite);

       #endif


        virtual void DrawRleBitmap(const PegPoint Where, const PegRect View,
                                   const PegBitmap *pGetmap);
        virtual void DrawTextView(PegPoint Where, const PEGCHAR *pText, 
                                  PegBrush &Brush, const PegFont *pFont, 
                                  PEGINT Count, PegRect &Rect);

        virtual PEGUBYTE *GetVideoAddress(void);
        virtual void HorizontalLine(PEGINT XStart, PEGINT XEnd, PEGINT YPos,
                                    PEGCOLOR Color, PEGINT Width);
        virtual void HorizontalLineXOR(PEGINT XStart, PEGINT XEnd, 
                                       PEGINT YPos);
        virtual void LineView(PEGINT xStart, PEGINT yStart, PEGINT xEnd, 
                              PEGINT yEnd, PegRect &Rect, PegBrush &Brush);

        virtual void PlotSubPixel(PegFixed xVal, PegFixed yVal,
            PEGCOLOR Color) {}

        virtual void RectMoveView(const PegRect &View,
                                  const PEGINT xMove, const PEGINT yMove);
        virtual void VerticalLine(PEGINT YStart, PEGINT YEnd, PEGINT XPos,
                                  PEGCOLOR Color, PEGINT Width);
        virtual void VerticalLineXOR(PEGINT YStart, PEGINT YEnd, PEGINT XPos);

        PEGUBYTE mPalette[16 * 3];
       #ifdef PEGWIN32        
        PEGUBYTE FAR *mpSecondBuffer;
       #endif

	private:
		void Draw16ColorBitmap(const PegPoint Where, const PegBitmap *pGetmap,
            const PegRect &View);
        void DrawUnaligned16ColorBitmap(const PegPoint Where, const PegBitmap *pGetmap,
            const PegRect &View);
};

#endif



